home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Syslog Component / ShowInitIcon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-25  |  5.7 KB  |  167 lines  |  [TEXT/SPM ]

  1. /*
  2.     ShowInitIcon - version 1.0, May 11th, 1995
  3.     This code is intended to let INIT writers easily display an icon at startup time.
  4.     View in Geneva 9pt, 4-space tabs
  5.  
  6.     Written by: Peter N Lewis <peter@mail.peter.com.au>, Jim Walker <JWWalker@aol.com>
  7.     and François Pottier <pottier@dmi.ens.fr>, with thanks to previous ShowINIT authors.
  8.     Send comments and bug reports to François Pottier.
  9.     
  10.     This version features:
  11.     - Short and readable code.
  12.     - Correctly wraps around when more than one row of icons has been displayed.
  13.     - works with System 6
  14.     - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
  15. */
  16.  
  17. #include "ShowInitIcon.h"
  18.  
  19. #include <Resources.h>
  20. #include <Icons.h>
  21. #include <OSUtils.h>
  22. #include <LowMem.h>
  23.  
  24. // You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
  25.  
  26. // Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
  27. // Set it to 0 if you want to include this source file into your INIT project.
  28.  
  29. #if 0
  30. #define ShowInitIcon main
  31. #endif
  32.  
  33. // The ShowINIT mechanism works by having each INIT read/write data from these globals.
  34.  
  35. #define LMGetVCoord()            (*((short*)0x092A))
  36. #define LMGetVCheckSum()        (*((short*)0x0928))
  37. #define LMGetHCoord()            (*((short*)0x092C))
  38. #define LMGetHCheckSum()        (*((short*)0x092E))
  39.  
  40. #define LMSetVCoord(val)            (*((short*)0x092A)=(val))
  41. #define LMSetVCheckSum(val)        (*((short*)0x0928)=(val))
  42. #define LMSetHCoord(val)            (*((short*)0x092C)=(val))
  43. #define LMSetHCheckSum(val)        (*((short*)0x092E)=(val))
  44.  
  45. // Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
  46.  
  47. static unsigned short CheckSum (unsigned short x);
  48. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
  49. static void AdvanceIconPosition (Rect* iconRect);
  50. static void DrawBWIcon (short iconID, Rect *iconRect);
  51.  
  52. typedef struct QDStorageStruct QDStorage;
  53.  
  54. /* Modified to ensure alignment is set for 68k code - DHN */
  55. #if defined(powerc) || defined (__powerc)
  56. #pragma options align=mac68k
  57. #endif
  58. struct QDStorageStruct {
  59.     QDGlobals            qd;                                    // Storage for the QuickDraw globals
  60.     long                qdGlobalsPtr;                            // A5 points to this place; it will contain a pointer to qd
  61. };
  62. #if defined(powerc) || defined(__powerc)
  63. #pragma options align=reset
  64. #endif
  65.  
  66. // Main routine.
  67. pascal void ShowInitIcon (short iconFamilyID, Boolean advance){
  68.     long                oldA5;                                // Original value of register A5
  69.     QDStorage            qds;                                    // Fake QD globals
  70.     CGrafPort            colorPort;
  71.     GrafPort            bwPort;
  72.     Rect            destRect;
  73.     SysEnvRec        environment;                            // Machine configuration.
  74.     
  75.     oldA5 = SetA5((long) &qds.qdGlobalsPtr);                    // Tell A5 to point to the end of the fake QD Globals
  76.     InitGraf(&qds.qd.thePort);                                // Initialize the fake QD Globals
  77.     
  78.     SysEnvirons(curSysEnvVers, &environment);                    // Find out what kind of machine this is
  79.  
  80.     ComputeIconRect(&destRect, &qds.qd.screenBits.bounds);            // Compute where the icon should be drawn
  81.  
  82.     if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
  83.         OpenCPort(&colorPort);
  84.         PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
  85.         CloseCPort(&colorPort);
  86.     } else {
  87.         OpenPort(&bwPort);
  88.         DrawBWIcon(iconFamilyID, &destRect);
  89.         ClosePort(&bwPort);
  90.     }
  91.     
  92.     if (advance)
  93.         AdvanceIconPosition (&destRect);
  94.         
  95.     SetA5(oldA5);                                             // Restore A5 to its previous value
  96. }
  97.  
  98. // A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
  99. static unsigned short CheckSum (unsigned short x){
  100.     return ((x << 1) | (x >> 15)) ^ 0x1021;
  101. }
  102.  
  103. // ComputeIconRect computes where the icon should be displayed.
  104. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds){
  105.     if (CheckSum(LMGetHCoord()) != LMGetHCheckSum())            // If we are first, we need to initialize the shared data.
  106.         LMSetHCoord(8);
  107.     if (CheckSum(LMGetVCoord()) != LMGetVCheckSum())
  108.         LMSetVCoord(screenBounds->bottom - 40);
  109.     
  110.     if (LMGetHCoord() + 34 > screenBounds->right) {                // Check whether we must wrap
  111.         iconRect->left = 8;
  112.         iconRect->top = LMGetVCoord() - 40;
  113.     } else {
  114.         iconRect->left = LMGetHCoord();
  115.         iconRect->top = LMGetVCoord();
  116.     }
  117.     iconRect->right = iconRect->left + 32;
  118.     iconRect->bottom = iconRect->top + 32;
  119. }
  120.  
  121. // AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
  122. static void AdvanceIconPosition (Rect* iconRect){
  123.     LMSetHCoord(iconRect->left + 40);                            // Update the shared data
  124.     LMSetVCoord(iconRect->top);
  125.     LMSetHCheckSum(CheckSum(LMGetHCoord()));
  126.     LMSetVCheckSum(CheckSum(LMGetVCoord()));
  127. }
  128.  
  129. // DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
  130. static void DrawBWIcon (short iconID, Rect *iconRect){
  131.     Handle        icon;
  132.     BitMap        source, destination;
  133.     GrafPtr        port;
  134.     
  135.     icon = Get1Resource('ICN#', iconID);
  136.     if (icon) {
  137.         HLock(icon);
  138.                                                         // Prepare the source and destination bitmaps.
  139.         source.baseAddr = *icon + 128;                        // Mask address.
  140.         source.rowBytes = 4;
  141.         SetRect(&source.bounds, 0, 0, 32, 32);
  142.         GetPort(&port);
  143.         destination = port->portBits;
  144.                                                         // Transfer the mask.
  145.         CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
  146.                                                         // Then the icon.
  147.         source.baseAddr = *icon;
  148.         CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
  149.     }
  150. }
  151.  
  152. /*
  153.     Notes
  154.     
  155.     Checking for PlotIconID:
  156.         We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
  157.         Otherwise we use B&W grafport and draw using PlotBWIcon.
  158.     
  159.     68k Struct Padding:
  160.         I (DHN) added the padding stuff to ensure that everything pads well when building for the PPC.  I have been bitten
  161.         already by a non-padded structure that didn't work on a PPC that did on a 68k Mac, so I use the padding religiously now.
  162.     
  163.     
  164. */
  165.  
  166.  
  167.